home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / feel0_89.lha / Feel / Modules / streams1.em < prev    next >
Lisp/Scheme  |  1993-07-15  |  18KB  |  639 lines

  1. ;; Eulisp Module
  2. ;; Author: pab
  3. ;; File: streams.em
  4. ;; Date: Sun Jun  6 18:06:33 1993
  5. ;;
  6. ;; Project:
  7. ;; Description: 
  8. ;;
  9.  
  10. (defmodule streams1
  11.   (extras0
  12.    macros0
  13.    numbers
  14.    defs
  15.    telos1
  16.    init
  17.    )
  18.   ()
  19.  
  20.   (export generic-prin output open popen flush 
  21.       close prin print write newline input uninput
  22.       read-line end-of-stream-p stream-position)
  23.   
  24.   (export scan format)
  25.  
  26.   (defstruct <char-file-stream> ()
  27.     ((file accessor file-stream-file)
  28.      (name initarg name accessor file-stream-name)
  29.      (mode accessor file-stream-mode))
  30.     constructor (make-file-stream name)
  31.     )
  32.  
  33.   (defstruct <pipe-stream> <char-file-stream>
  34.     ()
  35.     constructor make-pipe-stream
  36.     )
  37.  
  38.   ;; generic operations
  39.   (defgeneric close (stream))
  40.   (defgeneric stream-position (stream))
  41.   (defgeneric (setter stream-position) (stream val))
  42.   ;;(defgeneric read (stream))
  43.   (defgeneric input (stream))
  44.   (defgeneric uninput (stream obj))
  45.   (defgeneric read-line (stream))
  46.  
  47.   ;; Opening a file
  48.  
  49.   (defun open (name . options)
  50.     (let ((mode (find-mode options))
  51.       (new (make-file-stream (convert name <string>)))
  52.       (reopen (scan-args 'reopen options null-argument)))
  53.       ((setter file-stream-file) new (if reopen 
  54.                      (freopen reopen)
  55.                        (fopen name mode)))
  56.       ((setter file-stream-mode) new mode)
  57.       new))
  58.   
  59.   (defun popen (name . options)
  60.     (let ((mode (find-mode options))
  61.       (new (make-pipe-stream (convert name <string>))))
  62.       ((setter file-stream-file) new (fpopen name mode))
  63.       ((setter file-stream-mode) new mode)
  64.       new))
  65.   
  66.   (defun find-mode (options)
  67.     (if (null options)
  68.     "r"
  69.       (let ((read-flag (scan-args 'input options null-argument))
  70.         (write-flag (scan-args 'output options null-argument))
  71.         (update-flag (scan-args 'update options null-argument))
  72.         (append-flag (scan-args 'append options null-argument)))
  73.     (cond ((and append-flag update-flag) "a+")
  74.           (append-flag "a")
  75.           ((and write-flag (or read-flag update-flag)) "r+")
  76.           (write-flag "w")
  77.           (read-flag "r")
  78.           (t (error "open: no useful flags" <stream-error>))))))
  79.  
  80.   ;; Writing to a raw file
  81.  
  82.   (defmethod output ((x <char-file-stream>) o)
  83.     (fput (file-stream-file x) o))
  84.  
  85.   ;; Sort out standard streams
  86.  
  87.   ;; reading
  88.   ;; Reading _should_ invoke the input method.
  89.   ;; unfortunately this means much hacking with lex.
  90.  
  91.   (defmethod generic-read ((stream <char-file-stream>))
  92.     (fread (file-stream-file stream)))
  93.   
  94.   (defmethod input ((stream <char-file-stream>))
  95.     (fread-char (file-stream-file stream)))
  96.  
  97.   (defmethod uninput ((stream <char-file-stream>) (c <character>))
  98.     (fungetc (file-stream-file stream) c))
  99.  
  100.   (defun end-of-stream-p (stream)
  101.     (let ((c (input stream)))
  102.       (if (eq c *eof*) t
  103.     (uninput stream c))))
  104.  
  105.   (defmethod read-line ((s <char-file-stream>))
  106.     (fread-line (file-stream-file s)))
  107.   
  108.   ;; default method...
  109.   (defmethod read-line ((s <object>))
  110.     (labels ((aux1 (n l)
  111.            (let ((c (input s)))
  112.              (if (eq c #\newline)
  113.              (let ((string (make-string (+ n 1))))
  114.                (labels ((aux2 (n l)
  115.                       (if (null l) nil
  116.                         (progn ((setter string-ref) string n (car l))
  117.                            (aux2 (- n 1) (cdr l))))))
  118.                    (aux2 (- n 1) l))
  119.                ((setter string-ref) string n #\newline)
  120.                string)
  121.                (aux1 (+ n 1) (cons c l))))))
  122.         (aux1 0 nil)))
  123.  
  124.  
  125.   ;; Others..
  126.   (defmethod (setter stream-position) ((stream <char-file-stream>) pos)
  127.     (fseek (file-stream-file stream) pos))
  128.  
  129.   (defmethod stream-position ((stream <char-file-stream>))
  130.     (ftell (file-stream-file stream)))
  131.  
  132.   (defmethod close ((stream <char-file-stream>))
  133.     (fclose (file-stream-file stream)))
  134.  
  135.   (defmethod flush ((stream <char-file-stream>))
  136.     (fflush (file-stream-file stream)))
  137.   
  138.   (defun prin (x . s)
  139.     (generic-prin x (if (null s)
  140.             (standard-output-stream)
  141.               (car s))))
  142.   
  143.   (defun print (x . s)
  144.     (let ((s (if (null s)
  145.             (standard-output-stream)
  146.               (car s))) )
  147.       (generic-prin x s)
  148.       (generic-prin #\newline s))
  149.     x)
  150.   
  151.   (defun write (x . s)
  152.     (generic-write x (if (null s)
  153.             (standard-output-stream)
  154.               (car s))))
  155.   
  156.   (defun newline s
  157.     (prin #\newline (if s (car s) (standard-output-stream))))
  158.  
  159.  
  160.   ;; Simple printing
  161.   
  162.   (defmethod generic-prin ((x <class>) s)
  163.     (format s "#<~a: ~a>" 
  164.         (symbol-unbraced-name (class-name (class-of x)))
  165.         (symbol-unbraced-name (class-name x)))
  166.     x)
  167.  
  168.   (defmethod generic-prin ((x <pair>) s)
  169.     (print-list x s))
  170.  
  171.   (defmethod generic-prin ((x <null>) s)
  172.     (generic-prin "()" s)
  173.     nil)
  174.   
  175.   (defmethod generic-prin ((x <symbol>) s)
  176.     (generic-prin (symbol-name x) s)
  177.     x)
  178.  
  179.   (defmethod generic-prin ((x <string>) s)
  180.     (output s x))
  181.  
  182.   (defmethod generic-prin ((x <integer>) s)
  183.     (print-fixnum x s) x)
  184.  
  185.   (defmethod generic-prin ((x <double-float>) s)
  186.     (format s "~f" x) x)
  187.  
  188.   (defmethod generic-prin ((x <character>) s)
  189.     (if (eq x *eof*)
  190.     (generic-prin "<<EOF>>" s)
  191.       (output s x)))
  192.  
  193.   (defmethod generic-prin ((x <vector>) s)
  194.     (generic-prin "#(" s)
  195.     (let ((l (length x)))
  196.       (cond ((= l 0)
  197.          nil)
  198.         (t 
  199.          (labels ((aux (n)
  200.                (if (= n (length x)) nil
  201.                  (progn (generic-prin " " s)
  202.                     (generic-prin (vector-ref x n) s)
  203.                     (aux (+ n 1))))))
  204.              (generic-prin (vector-ref x 0) s)
  205.              (aux 1)))))
  206.     (generic-prin ")" s))
  207.  
  208.   (defmethod generic-prin ((x <generic-function>) stream)
  209.     (format stream "#<~a: ~a>" (symbol-unbraced-name (class-name (class-of x))) (generic-name x)))
  210.  
  211.   (defmethod generic-prin ((x <method>) stream)
  212.     (format stream "#<method: ~a (~a)>" 
  213.         (if (null (method-generic-function x)) 
  214.         "{unattached}"
  215.           (generic-name (method-generic-function x)))
  216.         (mapcar class-name (method-signature x))))
  217.  
  218.   (defmethod generic-prin ((x <i-function>) s)
  219.     (format s "#<~a: (lambda ~a~l) @ ~a>"
  220.         (symbol-unbraced-name (class-name (class-of x)))
  221.         (function-lambda-list x)
  222.         (lambda (l s)
  223.           (mapc (lambda (o)
  224.               (generic-prin " " s)
  225.               (generic-write o s))
  226.             l))
  227.         (i-function-body x)
  228.         (primitive-slot-ref-0 (function-home x))))
  229.  
  230.   (defmethod generic-prin ((x <c-function>) s)
  231.     (format s "#<~a: ~a ~a @ ~a>"
  232.         (symbol-unbraced-name (class-name (class-of x)))
  233.         (function-name x)
  234.         (let ((ll (function-lambda-list x)))
  235.           (if (consp ll)
  236.           (if (consp (last-pair ll))
  237.               (length ll)
  238.             (- (list-length ll) 1))
  239.         -1))
  240.         (primitive-slot-ref-0 (function-home x))))
  241.     
  242.   (defmethod generic-prin ((x <object>) s)
  243.     (format s "#<~a: ~u>" 
  244.         (symbol-unbraced-name (class-name (class-of x)))
  245.         x)
  246.     x)
  247.  
  248.   ;; generic-write
  249.  
  250.   (defmethod generic-write ((x <null>) s)
  251.     (generic-prin x s))
  252.  
  253.   (defun print-escaped-sym (x s)
  254.     (generic-prin "|" s)
  255.     (labels ((aux (n m)
  256.           (if (= n m) nil
  257.             (let ((c (string-ref x n) s))
  258.               (when (or (eq c #\\) (eq c #\|))
  259.             (generic-prin #\\ s))
  260.               (generic-prin c s)
  261.               (aux (+ n 1) m)))))
  262.         (aux 0 (length x)))
  263.     (generic-prin "|" s))
  264.     
  265.  
  266.   (defmethod generic-write ((x <symbol>) s)
  267.     (let ((name (symbol-name x)))
  268.       (if (escaped-id-p name) 
  269.       (print-escaped-sym name s)
  270.     (generic-prin name s))))
  271.   
  272.   (defmethod generic-write ((x <vector>) s)
  273.     (generic-prin "#(" s)
  274.     (let ((l (length x)))
  275.       (cond ((= l 0)
  276.          nil)
  277.         (t 
  278.          (labels ((aux (n)
  279.                (if (= n (length x)) nil
  280.                  (progn (generic-prin " " s)
  281.                     (generic-write (vector-ref x n) s)
  282.                     (aux (+ n 1))))))
  283.              (generic-write (vector-ref x 0) s)
  284.              (aux 1)))))
  285.     (generic-prin ")" s))
  286.   
  287.   (defmethod generic-write ((l <pair>) s)
  288.     (generic-prin "(" s)
  289.     (labels ((aux (l)
  290.           (cond ((consp (cdr l))
  291.              (generic-write (car l) s)
  292.              (generic-prin " " s)
  293.              (aux (cdr l)))
  294.             ((null (cdr l))
  295.              (generic-write (car l) s)
  296.              (generic-prin ")" s))
  297.             (t (generic-write (car l) s)
  298.                (generic-prin " . " s)
  299.                (generic-write (cdr l) s)
  300.                (generic-prin ")" s)))))
  301.         (aux l)))
  302.  
  303.   (defconstant escape-table (make-table))
  304.  
  305.   (labels ((aux (l)
  306.         (if (null l) nil
  307.           (progn ((setter sys-table-ref) escape-table
  308.               (car (car l)) (cdr (car l)))
  309.              (aux (cdr l))))))
  310.       (aux '((#\newline . newline) (#\tab . tab) 
  311.          (#\space . space) (#\return . return))))
  312.   
  313.   (defmethod generic-write ((c <character>) s)
  314.     (progn (generic-prin "#\\" s)
  315.        (let ((esc (sys-table-ref escape-table c)))
  316.          (if esc (generic-prin esc s)
  317.            (generic-prin c s)))))
  318.  
  319.   (defconstant string-escapes (make-table))
  320.   (mapc (lambda (l)
  321.         ((setter sys-table-ref) string-escapes (car l) (cdr l)))
  322.       '((#\\ . "\\\\") (#\" . "\\\"") (#\newline . "\\n")))
  323.         
  324.   (defun find-esc (c)
  325.     (let ((val (convert c <integer>)))
  326.       (if (or (< val 32) (> val 128))
  327.       (format nil "\\~d"  (convert c <integer>))
  328.     (sys-table-ref string-escapes c))))
  329.  
  330.   (defun print-escaped-string (s stream)
  331.     (labels ((aux (n m)
  332.           (if (= n m)
  333.               nil
  334.             (let* ((c (string-ref s n))
  335.                (esc (find-esc c)))
  336.               (generic-prin 
  337.                (if (null esc) c
  338.              esc)
  339.                stream)
  340.               (aux (+ n 1) m)))))
  341.         (aux 0 (length s))))
  342.             
  343.   (defmethod generic-write ((s <string>) stream)
  344.     (generic-prin "\"" stream)
  345.     (if (escaped-id-p s)
  346.     (print-escaped-string s stream)
  347.       (generic-prin s stream))
  348.     (generic-prin "\"" stream)
  349.     s)
  350.  
  351.   ;; Format...
  352.   (defun a-formatter (stream args other)
  353.     ;;(GC)
  354.     (if (null args)
  355.     (error "format: no args" <format-error>)
  356.       (progn (generic-prin (car args) stream)
  357.          (cdr args))))
  358.  
  359.   (defun s-formatter (stream args other)
  360.     (if (null args)
  361.     (error "format: no args" <format-error>)
  362.       (progn (generic-write (car args) stream)
  363.          (cdr args))))
  364.  
  365.   (defun d-formatter (stream args other)
  366.     (if (null args)
  367.     (error "format: no args" <format-error>)
  368.       (progn (print-fixnum (car args) stream)
  369.          (cdr args))))
  370.  
  371.   (defun l-formatter (stream args other)
  372.     (if (or (null args) (null (cdr args)))
  373.     (error "format: no args" <format-error>)
  374.       (progn ((car args) (cadr args) stream)
  375.          (cddr args))))
  376.  
  377.   (defun simple-formatter (c)
  378.     (lambda (stream args other)
  379.     (progn (output stream c)
  380.            args)))
  381.  
  382.   ((setter formatter) #\a a-formatter)
  383.   ((setter formatter) #\b b-formatter)
  384.   ((setter formatter) #\d a-formatter)
  385.   
  386.   ((setter formatter) #\e e-formatter)
  387.   ((setter formatter) #\f f-formatter)
  388.   ((setter formatter) #\g g-formatter)
  389.  
  390.   ((setter formatter) #\l l-formatter)
  391.  
  392.   ;;((setter formatter) #\o o-formatter)
  393.   ;;((setter formatter) #\r r-formatter)
  394.   ((setter formatter) #\s s-formatter)
  395.   ((setter formatter) #\u u-formatter)
  396.   ((setter formatter) #\t (simple-formatter #\tab))
  397.   ((setter formatter) #\% (simple-formatter #\newline))
  398.   ((setter formatter) #\| (simple-formatter #\|))
  399.   ;; actually wrong (in some ways...)
  400.   ((setter formatter) #\& (simple-formatter #\newline))
  401.   
  402.   ((setter formatter) #\~ (simple-formatter #\~))
  403.   
  404.  
  405.   ;; Output side done
  406.   ;; Set things up
  407.   ((setter standard-input-stream) (open "stdin" 'reopen 0 'input t))
  408.   ((setter standard-output-stream) (open "stdout" 'reopen 1 'output t))
  409.   ((setter standard-error-stream) (open "stderr" 'reopen 2 'output t))
  410.  
  411.   ;; Scan...
  412.   (defun substring-copy (sdest ssource start len)
  413.     (labels ((aux (n m)
  414.           (if (= n m) nil
  415.             (progn ((setter string-ref) sdest n 
  416.                 (string-ref ssource (+ n start)))
  417.                (aux (+ n 1) m)))))
  418.         (aux 0 len)))
  419.  
  420.   (defconstant whitespace-tab (make-table))
  421.   (mapcar (lambda (c)
  422.         ((setter sys-table-ref) whitespace-tab c t))
  423.       '(#\space #\tab #\newline #\return))
  424.  
  425.   (defun whitespacep (c)
  426.     (sys-table-ref whitespace-tab c))
  427.  
  428.   (defconstant scan-fns (make-table))
  429.   (defun scanner (c)
  430.     (sys-table-ref scan-fns c))
  431.  
  432.   ((setter setter) scanner
  433.    (lambda (c x)
  434.      ((setter sys-table-ref) scan-fns c x)))
  435.  
  436.   (defgeneric scan (stream s))
  437.   
  438.   (defmethod scan ((x <null>) s)
  439.     (scan (standard-input-stream) s))
  440.  
  441.   (defmethod scan ((x <symbol>) s)
  442.     (if (eq x t)
  443.     (scan (standard-input-stream) s)
  444.       (error "scan: illegal stream" <format-error>)))
  445.  
  446.   (defun find-scanner (pat n)
  447.     (if (= n (length pat))
  448.     (error "scan: ~ at end of string" <scan-mismatch>)
  449.       (let ((fn (scanner (string-ref pat n))))
  450.     (if (null fn)
  451.         (error "Scan: unknown scan directive" <scan-mismatch> 'error-value (string-ref pat n))
  452.       fn))))
  453.   
  454.   (defmethod scan ((s <object>) pat)
  455.     (labels ((aux (last n m result)
  456.           (cond ((= n m)
  457.              (scan-literal-string last m)
  458.              (reverse-list result))
  459.             ((whitespacep (string-ref pat n))
  460.              (eat-whitespace s)
  461.              (format t "lit: ~s~%" (if (= last n) "" (substring pat last (- n 1))))
  462.              (scan-literal-string last n)
  463.              (aux (+ n 1) (+ n 1) m result))
  464.             ((eq (string-ref pat n) #\~)
  465.              (scan-literal-string last n)
  466.              (let ((scanner (find-scanner pat (+ n 1)) ))
  467.                 (if (null (car scanner))
  468.                 (progn (handle-errors (cdr scanner) s result)
  469.                       (aux (+ n 2) (+ n 2) m result))
  470.                  (aux (+ n 2) (+ n 2) m 
  471.                   (cons (handle-errors (cdr scanner) s result) result)))))
  472.             (t (aux last (+ n 1) m result))))
  473.          (scan-literal-string (start end)
  474.                   (if (= start end) t
  475.                     (let ((c (input s)))
  476.                       (if (eq c (string-ref pat start))
  477.                       (scan-literal-string (+ start 1) end)
  478.                     (progn (uninput s c)
  479.                            (error "scan: literal mismatch" <scan-mismatch> )))))))
  480.         (aux 0 0 (length pat) nil)))
  481.   
  482.   (defun handle-errors (fn stream val)
  483.     (with-handler (lambda (cond cont)
  484.             ((setter condition-error-value) 
  485.              cond val))
  486.           (fn stream)))
  487.  
  488.   (defun eat-whitespace (stream)
  489.     (let ((c (input stream)))
  490.       (if (whitespacep c)
  491.       (eat-whitespace stream)
  492.         (uninput stream c))))
  493.  
  494.   ;; Coded for speed of coding...
  495.   
  496.   ;; buggy: assumes A<a
  497.   (defun make-digit (char)
  498.     (let ((code (convert char <integer>)))
  499.       (cond ((> code (convert #\a <integer>))
  500.          (- code (convert #\a <integer>)))
  501.         ((> code (convert #\A <integer>))
  502.          (- code (convert #\A <integer>)))      
  503.         (t (- code (convert #\0 <integer>))))))
  504.          
  505.   (defun base-scanner (base floatp)
  506.     (lambda (stream)
  507.       (labels ((aux (acc div)
  508.             (let* ((c (input stream))
  509.                (digit (make-digit c)))
  510.               (cond ((and (< digit base)
  511.                   (> digit -1))
  512.                  (if (= div 0)
  513.                  (aux (+ (* acc base) digit) 0)
  514.                    (aux (+ acc (/ digit div)) 
  515.                     (* div base))))
  516.                 ((and (eq c #\.) floatp (= div 0))
  517.                  (aux (convert acc <double-float>)
  518.                   (convert base <double-float>)))
  519.                 (t (progn (uninput stream c)
  520.                       acc)))))
  521.            (scan-+ve-int (c)
  522.                  (let ((digit-1 (make-digit c)))
  523.                    (if (and (< digit-1 base)
  524.                     (> digit-1 -1))
  525.                    (aux digit-1 0)
  526.                  (progn (uninput stream c)
  527.                     (error "No digit on stream" <scan-mismatch>)))))
  528.            (scan-int ()
  529.              (let ((c (input stream)))
  530.                (if (eq c #\-)
  531.                    (- (scan-+ve-int (input stream)))
  532.                  (scan-+ve-int c)))))
  533.           (eat-whitespace stream)
  534.           (scan-int))))
  535.   
  536.   (defun float-scanner (stream)
  537.     ((base-scanner 10 t) stream))
  538.  
  539.   ;; assumed to be float..
  540.   (defun pow (val n)
  541.     (exp (* n (log val))))
  542.  
  543.   (defun s-scanner (stream)
  544.     (labels ((aux (l)
  545.           (let ((c (input stream)))
  546.             (if (whitespacep c)
  547.             (progn (uninput stream c)
  548.                    (fold (lambda (c s)
  549.                        (string-append (convert c <string>)
  550.                               s))
  551.                      l
  552.                      ""))
  553.               (aux (cons c l))))))
  554.         (eat-whitespace stream)
  555.         (aux nil)))
  556.  
  557.   (defun newline-scanner (s)
  558.     (let ((c (input s)))
  559.       (cond ((eq c #\newline) t)
  560.         ((eq c *eof*)
  561.          nil)
  562.         ((whitespacep c)
  563.          (newline-scanner s))
  564.         (t (uninput s c)
  565.            (error "scan: expected newline" <scan-mismatch> 'error-value c)))))
  566.   
  567.   (defun r-scanner (stream)
  568.     (let ((radix (scan stream "~dr")))
  569.       (let ((v2 ((base-scanner radix nil) stream)))
  570.     v2)))
  571.   
  572.   (defun c-scanner (stream)
  573.     (input stream))
  574.  
  575.   (defun returning (x) (cons t x))
  576.   (defun non-returning (x) (cons nil x))
  577.   
  578.   ((setter scanner) #\b (returning (base-scanner 2 nil)))
  579.   ((setter scanner) #\c (returning c-scanner))
  580.   ((setter scanner) #\d (returning (base-scanner 10 nil)))
  581.   ((setter scanner) #\f (returning (base-scanner 10 t)))
  582.   ((setter scanner) #\o (returning (base-scanner 8 nil)))
  583.   ((setter scanner) #\r (returning r-scanner))
  584.   ((setter scanner) #\s (returning s-scanner))
  585.   ((setter scanner) #\t (non-returning s-scanner))
  586.   ((setter scanner) #\x (returning (base-scanner 16 nil)))
  587.   ((setter scanner) #\% (non-returning newline-scanner))
  588.  
  589.   ;; For format nil...
  590.   (defstruct <string-stream> ()
  591.     ((content initform nil accessor string-stream-content)
  592.      (size initform 0 accessor string-stream-size))
  593.     constructor make-string-stream)
  594.  
  595.   (defmethod output ((x <string-stream>) s)
  596.     (let ((s (if (stringp s) (copy s)
  597.            (convert s <string>))))
  598.       ((setter string-stream-content) x
  599.        (cons s (string-stream-content x)))
  600.       ((setter string-stream-size) x 
  601.        (+ (string-stream-size x) (length s)))
  602.       s))
  603.  
  604.  
  605.   ;; should be clever and use length field...
  606.   ;; unfortunately, I dont have string-subrange-copy.
  607.   
  608.   (defmethod (converter <string>) ((x <string-stream>))
  609.     (fold (lambda (sub str)
  610.         (string-append sub str))
  611.       (string-stream-content x)
  612.       ""))
  613.  
  614.   ((setter format-string-stream-class) <string-stream>)
  615.  
  616.   (defun test (x)
  617.     (let ((s1  (read-line x)))
  618.       (format t "test string '~a'~%" s1)
  619.       (scan x s1)))
  620.   )
  621.  
  622.  
  623. Scan behaviour:
  624.  
  625. Raise an error on illegal input. Error value is things read in. number reading terminates on an illegal char.
  626. char pointer is left on the char that forced termination. Return value is list of values read.
  627.  
  628. Formats accepted: 
  629. ~b: binary number
  630. ~c: Character [may read a whitespace]
  631. ~d: decimal number
  632. ~f: floating point (e-notation not supported currently)
  633. ~o: octal number
  634. ~s: string, delimited by whitespace
  635. ~t: Read a string, and dump it
  636. ~x: hexadecimal number
  637. ~%: Match against a newline
  638.  
  639.